package org.pay.union.param.resp;

import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.pay.union.core.PlatForm;
import org.pay.union.enums.DebitCredit;
import org.pay.union.enums.TradeStateEnum;
import org.pay.union.enums.TradeTypeEnum;

import java.util.function.Function;

/***
 * @author Administrator
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel("基本查询对象")
public class BaseQueryResp extends BaseResp {


    /**
     * 以下字段在 status 和 result_code 都为 0的时候有返回
     * 交易状态
     * <p>
     * 是
     * <p>
     * String(32)
     * <p>
     * SUCCESS—支付成功
     * REFUND—转入退款
     * NOTPAY—未支付
     * CLOSED—已关闭
     * REVOKED/REVERSE—已撤销
     * USERPAYING—用户支付中
     * PAYERROR—支付失败(其他原因，如银行返回失败)
     * <p>
     * （支付结果以此字段为准）
     */
    @ApiModelProperty(value = "支付结果以此字段为准")
    protected String trade_state;


    /**
     * 交易状态描述
     * <p>
     * 否
     * <p>
     * String(256)
     * <p>
     * 对当前查询订单状态的描述
     * <p>
     * 以下字段在 trade_state为 SUCCESS的时候有返回
     */
    @ApiModelProperty(value = "交易状态描述")
    protected String trade_state_desc;


    /**
     * 交易类型
     * <p>
     * 是
     * <p>
     * String(32)
     * <p>
     * pay.weixin.micropay——微信被扫支付
     * pay.alipay.micropay——支付宝被扫支付
     * pay.unionpay.micropay——银联被扫支付
     */
    @ApiModelProperty(value = "交易类型")
    protected String trade_type;


    /**
     * 商户appid
     * <p>
     * 否
     * <p>
     * String
     * <p>
     * 受理商户appid
     */
    @ApiModelProperty(value = "商户appid")
    protected String appid;


    /**
     * 微信用户全局标识
     * <p>
     * 否
     * <p>
     * String(128)
     * <p>
     * <p>
     * 微信用户唯一标识码
     */
    @ApiModelProperty(value = "微信用户全局标识")
    protected String user_id;


    /**
     * 子商户appid
     * <p>
     * 否
     * <p>
     * String
     * <p>
     * 子商户appid
     */
    @ApiModelProperty(value = "子商户appid")
    protected String sub_appid;


    /**
     * 用户标识
     * <p>
     * 否
     * <p>
     * String(128)
     * <p>
     * 用户在受理商户 appid 下的唯一标识
     */
    @ApiModelProperty(value = "用户标识")
    protected String openid;


    /**
     * 用户标识
     * <p>
     * 否
     * <p>
     * String(128)
     * <p>
     * 用户在子商户appid下的唯一标识
     */
    @ApiModelProperty(value = "用户标识")
    protected String sub_openid;


    /**
     * 是否关注公众账号
     * <p>
     * 否
     * <p>
     * String(1)
     * <p>
     * 用户是否关注公众账号，Y-关注，N-未关注，仅在公众账号类型支付有效
     */
    @ApiModelProperty(value = "是否关注公众账号")
    protected String is_subscribe;


    /**
     * 是否关注公众账号
     * <p>
     * 否
     * <p>
     * String(1)
     * <p>
     * 用户是否关注公众账号，Y-关注，N-未关注，仅在公众账号类型支付有效（子商户公众账号）
     */
    @ApiModelProperty(value = "是否关注公众账号")
    protected String sub_is_subscribe;


    /**
     * 平台订单号
     * <p>
     * 是
     * <p>
     * String(32
     * <p>
     * 平台交易号
     */
    @ApiModelProperty(value = "平台订单号")
    protected String transaction_id;


    /**
     * 第三方交易号
     * <p>
     * 是
     * <p>
     * String(32)
     * <p>
     * 第三方交易号
     */
    @ApiModelProperty(value = "第三方交易号")
    protected String out_transaction_id;


    /**
     * 商户订单号
     * <p>
     * 是
     * <p>
     * String(32)
     * <p>
     * 商户系统内部的定单号，32个字符内、可包含字母
     */
    @ApiModelProperty(value = "商户订单号")
    protected String out_trade_no;


    /**
     * 总金额
     * <p>
     * 是
     * <p>
     * Int
     * <p>
     * 总金额，以分为单位，不允许包含任何字、符号
     */
    @ApiModelProperty(value = "总金额")
    protected String total_fee;


    /**
     * 现金支付金额【微信】
     * <p>
     * 否
     * <p>
     * Int
     * <p>
     * 现金支付金额订单现金支付金额，详见支付金额
     */
    @ApiModelProperty(value = "现金支付金额【微信】")
    protected String cash_fee;


    /**
     * 优惠详情【微信】
     * <p>
     * 否
     * <p>
     * String(6000)
     * <p>
     * 微信优惠详情，透传微信官方营销详情字段，json格式字符串
     */
    @ApiModelProperty(value = "优惠详情【微信】")
    protected String romotion_detail;


    /**
     * 优惠详情【银联】
     * <p>
     * 否
     * <p>
     * String
     * <p>
     * 优惠详情，银联二维码交易返回{"couponInfo":[{"id":"1201201901265194","desc":"宁城农商行超市二维码满50减10","type":"CP01","spnsrId":"QRA194853315031","offstAmt":"1000"}]}
     */
    @ApiModelProperty(value = "优惠详情【银联】")
    protected String unionpay_discount;

    /**
     * 开票金额 【支付宝】
     * <p>
     * 否
     * <p>
     * String(11)
     * <p>
     * 用户在交易中支付的可开发票的金额
     */
    @ApiModelProperty(value = "开票金额 【支付宝】")
    protected String invoice_amount;


    /**
     * 买家支付宝账号【支付宝】
     * <p>
     * 否
     * <p>
     * String(64)
     * <p>
     * 买家支付宝账号
     */
    @ApiModelProperty(value = "买家支付宝账号【支付宝】")
    protected String buyer_logon_id;


    /**
     * 买家付款金额【支付宝】
     * <p>
     * 否
     * <p>
     * Price
     * <p>
     * 买家付款的金额，单位为元，两位小数。
     */
    @ApiModelProperty(value = "买家付款金额【支付宝】")
    protected String buyer_pay_amount;


    /**
     * 买家支付宝用户ID【支付宝】
     * <p>
     * 否
     * <p>
     * String(28)
     * <p>
     * 买家在支付宝的用户id
     */
    @ApiModelProperty(value = "买家支付宝用户ID【支付宝】")
    protected String buyer_user_id;


    /**
     * 集分宝付款金额【支付宝】
     * <p>
     * 否
     * <p>
     * Price
     * <p>
     * 使用集分宝付款的金额，单位为元，两位小数。
     */
    @ApiModelProperty(value = "集分宝付款金额【支付宝】")
    protected String point_amount;


    /**
     * 实收金额【支付宝】
     * <p>
     * 否
     * <p>
     * Price
     * <p>
     * 实收金额，单位为元，两位小数。
     */
    @ApiModelProperty(value = "实收金额【支付宝】")
    protected String receipt_amount;


    /**
     * 交易支付使用的资金渠道 【支付宝】
     * 是
     * <p>
     * String
     * <p>
     * 示例值{"amount":"0.01","fundChannel":"PCREDIT"}
     */
    @ApiModelProperty(value = "交易支付使用的资金渠道 【支付宝】")
    protected String fund_bill_list;


    /**
     * 优惠详情【支付宝】
     * <p>
     * 否
     * <p>
     * String(1024)
     * <p>
     * 优惠详情，内容详见【单品优惠活动字段说明】
     */
    @ApiModelProperty(value = "优惠详情【支付宝】")
    protected String discount_goods_detail;

    /**
     * 现金券金额
     * <p>
     * 否
     * <p>
     * Int
     * <p>
     * 现金券支付金额<=订单总金额， 订单总金额-现金券金额为现金支付金额，以分为单位
     */
    @ApiModelProperty(value = "现金券金额")
    protected String coupon_fee;


    /**
     * 免充值优惠金额
     * <p>
     * 否
     * <p>
     * Int
     * <p>
     * 免充值优惠金额，以分为单位
     */
    @ApiModelProperty(value = "免充值优惠金额")
    protected String mdiscount;


    /**
     * 货币种类
     * <p>
     * 否
     * <p>
     * String(8)
     * <p>
     * 货币类型，符合 ISO 4217 标准的三位字母代码，默认人民币：CNY
     */
    @ApiModelProperty(value = "货币种类")
    protected String fee_type;

    /**
     * 附加信息
     * <p>
     * 否
     * <p>
     * String(127)
     * <p>
     * 商家数据包，原样返回
     */
    @ApiModelProperty(value = "附加信息")
    protected String attach;


    /**
     * 付款银行
     * <p>
     * 否
     * <p>
     * String(16)  银行类型
     */
    @ApiModelProperty(value = "付款银行")
    protected String bank_type;


    /**
     * 银行订单号
     * <p>
     * 否
     * <p>
     * String(32)
     * <p>
     * 银行订单号，若为微信支付则为空
     */
    @ApiModelProperty(value = "银行订单号")
    protected String bank_billno;


    /**
     * 支付完成时间
     * <p>
     * 是
     * <p>
     * String(14)
     * <p>
     * 支付完成时间，格式为yyyyMMddhhmmss，如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自平台服务器
     */
    @ApiModelProperty(value = "支付完成时间")
    protected String time_end;


    /**
     * 银联交易主键
     * 否
     * <p>
     * String(38)
     * <p>
     * 仅银联二维码交易有该字段信息，该字段的值里可能存在空格
     */
    @ApiModelProperty(value = "银联交易主键")
    protected String settle_key;

    @ApiModelProperty(value = "交易银行")
    protected String bank;

    @ApiModelProperty(value = "支付方式中文")
    protected String tradeTypeCn;//        支付方式中文


    public TradeTypeEnum tradeTypeEnum() {
        TradeTypeEnum tradeTypeEnum = TradeTypeEnum.codeOf(getTrade_type());
        if (tradeTypeEnum == null) {
            return null;
        }
        return tradeTypeEnum;
    }

    public TradeTypeEnum tradeType() {
        if (StrUtil.isBlank(trade_type)) {
            return null;
        }
        return TradeTypeEnum.codeOf(trade_type);
    }

    public TradeStateEnum tradeState() {
        if (StrUtil.isBlank(trade_state)) {
            return null;
        }
        return TradeStateEnum.valueOf(trade_state);
    }

    public String getBank() {
        if(StrUtil.isBlank(bank_type)){
            return null;
        }
        Function<String, DebitCredit> creditFunction = PlatForm.DEBIT_CREDIT_CENTER.get(tradeTypeEnum());
        if(creditFunction==null){
            return null;
        }
        return creditFunction.apply(bank_type).getBank();
    }

    public String getTradeTypeCn() {
        TradeTypeEnum tradeTypeEnum = tradeTypeEnum();
        return tradeTypeEnum==null?null:tradeTypeEnum.getCn();
    }
}
